package czk.concrent.stampLock;

import java.util.concurrent.locks.StampedLock;

/**
 * @Author:ChenZhangKun
 * @Date: 2020/7/23 22:57
 */
public class StampedLockDemo {
    public static void main(String[] args) throws InterruptedException {
        Container container=new Container(5);
        // 1 两个读锁，都是乐观锁情况
        // 2 一个读锁、一个写锁，会发生锁升级的情况
        new Thread(()->{
            // 读锁
            try {
                container.read(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
        Thread.sleep(500);
/*        new Thread(()->{
            // 读锁
            try {
                container.read(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();*/
        new Thread(()->{
            container.write(6);
        }).start();
    }
}
class Container{
    private int data;
    // 戳锁
    private final StampedLock lock=new StampedLock();

    public Container(int data) {
        this.data = data;
    }
    // 读方法
    public int read(int i) throws InterruptedException {
        long stamp = lock.tryOptimisticRead();
        System.out.println("乐观锁的邮戳为 "+stamp);
        // 开始乐观读锁
        Thread.sleep(i);
        if (lock.validate(stamp)){
            System.out.println("锁没被改");
            // 返回结果
            return data;
        }
        // 锁被改，升级成读锁
        System.out.println("锁升级");
        try {
            stamp = lock.readLock();
            System.out.println("升级后邮戳为 "+stamp);
            return data;
        }finally {
            lock.unlock(stamp);
        }
    }
    // 写方法
    public int write(int newData){
        long stamp = lock.writeLock();
        System.out.println("写锁 "+stamp);
        try {
            // 从新赋值
            this.data=newData;
        }finally {
            System.out.println("释放写锁");
            lock.unlock(stamp);
        }
        return newData;
    }
}
